home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2018 January / PCgo 01-2018 CD-ROM Germany.iso / nw.pak / Unnamed File 004936.txt < prev    next >
Encoding:
Text File  |  2015-07-29  |  7.0 KB  |  193 lines

  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. // Custom binding for the webRequestInternal API.
  6.  
  7. var binding = require('binding').Binding.create('webRequestInternal');
  8. var eventBindings = require('event_bindings');
  9. var sendRequest = require('sendRequest').sendRequest;
  10. var validate = require('schemaUtils').validate;
  11. var utils = require('utils');
  12. var idGeneratorNatives = requireNative('id_generator');
  13.  
  14. var webRequestInternal;
  15.  
  16. function GetUniqueSubEventName(eventName) {
  17.   return eventName + "/" + idGeneratorNatives.GetNextId();
  18. }
  19.  
  20. // WebRequestEventImpl object. This is used for special webRequest events
  21. // with extra parameters. Each invocation of addListener creates a new named
  22. // sub-event. That sub-event is associated with the extra parameters in the
  23. // browser process, so that only it is dispatched when the main event occurs
  24. // matching the extra parameters.
  25. //
  26. // Example:
  27. //   chrome.webRequest.onBeforeRequest.addListener(
  28. //       callback, {urls: 'http://*.google.com/*'});
  29. //   ^ callback will only be called for onBeforeRequests matching the filter.
  30. function WebRequestEventImpl(eventName, opt_argSchemas, opt_extraArgSchemas,
  31.                              opt_eventOptions, opt_webViewInstanceId) {
  32.   if (typeof eventName != 'string')
  33.     throw new Error('chrome.WebRequestEvent requires an event name.');
  34.  
  35.   this.eventName = eventName;
  36.   this.argSchemas = opt_argSchemas;
  37.   this.extraArgSchemas = opt_extraArgSchemas;
  38.   this.webViewInstanceId = opt_webViewInstanceId || 0;
  39.   this.subEvents = [];
  40.   this.eventOptions = eventBindings.parseEventOptions(opt_eventOptions);
  41.   if (this.eventOptions.supportsRules) {
  42.     this.eventForRules =
  43.         new eventBindings.Event(eventName, opt_argSchemas, opt_eventOptions,
  44.                                 opt_webViewInstanceId);
  45.   }
  46. }
  47.  
  48. // Test if the given callback is registered for this event.
  49. WebRequestEventImpl.prototype.hasListener = function(cb) {
  50.   if (!this.eventOptions.supportsListeners)
  51.     throw new Error('This event does not support listeners.');
  52.   return this.findListener_(cb) > -1;
  53. };
  54.  
  55. // Test if any callbacks are registered fur thus event.
  56. WebRequestEventImpl.prototype.hasListeners = function() {
  57.   if (!this.eventOptions.supportsListeners)
  58.     throw new Error('This event does not support listeners.');
  59.   return this.subEvents.length > 0;
  60. };
  61.  
  62. // Registers a callback to be called when this event is dispatched. If
  63. // opt_filter is specified, then the callback is only called for events that
  64. // match the given filters. If opt_extraInfo is specified, the given optional
  65. // info is sent to the callback.
  66. WebRequestEventImpl.prototype.addListener =
  67.     function(cb, opt_filter, opt_extraInfo) {
  68.   if (!this.eventOptions.supportsListeners)
  69.     throw new Error('This event does not support listeners.');
  70.   // NOTE(benjhayden) New APIs should not use this subEventName trick! It does
  71.   // not play well with event pages. See downloads.onDeterminingFilename and
  72.   // ExtensionDownloadsEventRouter for an alternative approach.
  73.   var subEventName = GetUniqueSubEventName(this.eventName);
  74.   // Note: this could fail to validate, in which case we would not add the
  75.   // subEvent listener.
  76.   validate($Array.slice(arguments, 1), this.extraArgSchemas);
  77.   webRequestInternal.addEventListener(
  78.       cb, opt_filter, opt_extraInfo, this.eventName, subEventName,
  79.       this.webViewInstanceId);
  80.  
  81.   var subEvent = new eventBindings.Event(subEventName, this.argSchemas);
  82.   var subEventCallback = cb;
  83.   if (opt_extraInfo && opt_extraInfo.indexOf('blocking') >= 0) {
  84.     var eventName = this.eventName;
  85.     subEventCallback = function() {
  86.       var requestId = arguments[0].requestId;
  87.       try {
  88.         var result = $Function.apply(cb, null, arguments);
  89.         webRequestInternal.eventHandled(
  90.             eventName, subEventName, requestId, result);
  91.       } catch (e) {
  92.         webRequestInternal.eventHandled(
  93.             eventName, subEventName, requestId);
  94.         throw e;
  95.       }
  96.     };
  97.   } else if (opt_extraInfo && opt_extraInfo.indexOf('asyncBlocking') >= 0) {
  98.     var eventName = this.eventName;
  99.     subEventCallback = function() {
  100.       var details = arguments[0];
  101.       var requestId = details.requestId;
  102.       var handledCallback = function(response) {
  103.         webRequestInternal.eventHandled(
  104.             eventName, subEventName, requestId, response);
  105.       };
  106.       $Function.apply(cb, null, [details, handledCallback]);
  107.     };
  108.   }
  109.   $Array.push(this.subEvents,
  110.       {subEvent: subEvent, callback: cb, subEventCallback: subEventCallback});
  111.   subEvent.addListener(subEventCallback);
  112. };
  113.  
  114. // Unregisters a callback.
  115. WebRequestEventImpl.prototype.removeListener = function(cb) {
  116.   if (!this.eventOptions.supportsListeners)
  117.     throw new Error('This event does not support listeners.');
  118.   var idx;
  119.   while ((idx = this.findListener_(cb)) >= 0) {
  120.     var e = this.subEvents[idx];
  121.     e.subEvent.removeListener(e.subEventCallback);
  122.     if (e.subEvent.hasListeners()) {
  123.       console.error(
  124.           'Internal error: webRequest subEvent has orphaned listeners.');
  125.     }
  126.     $Array.splice(this.subEvents, idx, 1);
  127.   }
  128. };
  129.  
  130. WebRequestEventImpl.prototype.findListener_ = function(cb) {
  131.   for (var i in this.subEvents) {
  132.     var e = this.subEvents[i];
  133.     if (e.callback === cb) {
  134.       if (e.subEvent.hasListener(e.subEventCallback))
  135.         return i;
  136.       console.error('Internal error: webRequest subEvent has no callback.');
  137.     }
  138.   }
  139.  
  140.   return -1;
  141. };
  142.  
  143. WebRequestEventImpl.prototype.addRules = function(rules, opt_cb) {
  144.   if (!this.eventOptions.supportsRules)
  145.     throw new Error('This event does not support rules.');
  146.   this.eventForRules.addRules(rules, opt_cb);
  147. };
  148.  
  149. WebRequestEventImpl.prototype.removeRules =
  150.     function(ruleIdentifiers, opt_cb) {
  151.   if (!this.eventOptions.supportsRules)
  152.     throw new Error('This event does not support rules.');
  153.   this.eventForRules.removeRules(ruleIdentifiers, opt_cb);
  154. };
  155.  
  156. WebRequestEventImpl.prototype.getRules = function(ruleIdentifiers, cb) {
  157.   if (!this.eventOptions.supportsRules)
  158.     throw new Error('This event does not support rules.');
  159.   this.eventForRules.getRules(ruleIdentifiers, cb);
  160. };
  161.  
  162. binding.registerCustomHook(function(api) {
  163.   var apiFunctions = api.apiFunctions;
  164.  
  165.   apiFunctions.setHandleRequest('addEventListener', function() {
  166.     var args = $Array.slice(arguments);
  167.     sendRequest(this.name, args, this.definition.parameters,
  168.                 {forIOThread: true});
  169.   });
  170.  
  171.   apiFunctions.setHandleRequest('eventHandled', function() {
  172.     var args = $Array.slice(arguments);
  173.     sendRequest(this.name, args, this.definition.parameters,
  174.                 {forIOThread: true});
  175.   });
  176. });
  177.  
  178. var WebRequestEvent = utils.expose('WebRequestEvent',
  179.                                    WebRequestEventImpl,
  180.                                    { functions: [
  181.   'hasListener',
  182.   'hasListeners',
  183.   'addListener',
  184.   'removeListener',
  185.   'addRules',
  186.   'removeRules',
  187.   'getRules'
  188. ] });
  189.  
  190. webRequestInternal = binding.generate();
  191. exports.binding = webRequestInternal;
  192. exports.WebRequestEvent = WebRequestEvent;
  193.